package set

import (
	"bytes"
	"fmt"
)

type HashSet struct {
	m map[interface{}] bool
}

func NewHashSet() *HashSet{
	return &HashSet{m: make(map[interface{}]bool)}
}

func (set *HashSet) Add(e interface{}) bool  {
	if !set.m[e] {
		set.m[e] = true
		return true
	}
	return false
}

func (set *HashSet) Remove(e interface{}) {
	delete(set.m, e)
}
func (set *HashSet) Clear() {
	set.m = make(map[interface{}]bool)
}
func (set *HashSet) Contains(e interface{}) bool {
	return set.m[e]
}
func (set *HashSet) Len() int {
	return len(set.m)
}
func (set *HashSet) Same(other Set) bool {
	if other == nil {
		return false
	}
	if set.Len() != other.Len(){
		return false
	}
	for key := range set.m {
		if !other.Contains(key){
			return false
		}
	}
	return true
}
func (set *HashSet) Elements() []interface{} {
	initLen := set.Len()
	result := make([]interface{}, initLen)
	actualLen := 0
	for key := range set.m {
		if actualLen < initLen{
			result[actualLen] = key
		}else{
			result = append(result, key)
		}
		actualLen ++
	}
	return result
}

func (set *HashSet) String() string {
	var buf bytes.Buffer
	buf.WriteString("HashSet{")
	first := true
	for key := range set.m {
		if first {
			first = false
		}else{
			buf.WriteString(", ")
		}
		buf.WriteString(fmt.Sprintf("%v", key))
	}
	buf.WriteString("}")
	return buf.String()
}